package com.tuanzi.loan.business.service.pageTemplate.impl;

import com.google.common.collect.Lists;
import com.tuanzi.loan.business.entity.CurrentUser;
import com.tuanzi.loan.business.entity.LoginUser;
import com.tuanzi.loan.business.entity.common.CommProductId;
import com.tuanzi.loan.business.entity.pageTemplate.LoanPageTemplateInfo;
import com.tuanzi.loan.business.entity.pageTemplate.LoanPageTemplateModule;
import com.tuanzi.loan.business.entity.pageTemplate.LoanPageTemplateProduct;
import com.tuanzi.loan.business.repository.pageTemplate.LoanPageTemplateInfoRepository;
import com.tuanzi.loan.business.repository.pageTemplate.LoanPageTemplateModuleRepository;
import com.tuanzi.loan.business.repository.pageTemplate.LoanPageTemplateProductRepository;
import com.tuanzi.loan.business.service.pageTemplate.LoanPageTemplateInfoService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.repository.JPAAuditRepository;
import com.tuanzi.loan.core.service.BaseAuditServiceImpl;
import com.tuanzi.loan.core.vo.PageSearcher;
import com.tuanzi.loan.vo.request.pageTemplate.LoanPageTemplateInfoRequest;
import com.tuanzi.loan.vo.response.pageTemplate.LoanPageTemplateInfoResponse;
import com.tuanzi.loan.vo.view.pageTemplate.LoanPageTemplateInfoView;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * @Auther: hequnayu
 * @Date: 2019/9/17 11:14
 * @Description:
 */
@Slf4j
@Debug
@Service
@Transactional
public class LoanPageTemplateInfoServiceImpl extends BaseAuditServiceImpl<LoanPageTemplateInfo,Long> implements LoanPageTemplateInfoService {

    @Autowired
    private LoanPageTemplateInfoRepository templateInfoRepository;
    @Autowired
    private LoanPageTemplateModuleRepository moduleRepository;
    @Autowired
    private LoanPageTemplateProductRepository productRepository;

    @Override
    protected JPAAuditRepository<LoanPageTemplateInfo, Long> getRepository() {
        return templateInfoRepository;
    }

    @Override
    public Page<LoanPageTemplateInfoResponse> list(PageSearcher<LoanPageTemplateInfoRequest> pageSearcher) {
        return templateInfoRepository.list(pageSearcher.getSearchCondition(), pageSearcher.getPageable());
    }

    @Override
    public LoanPageTemplateInfo savePageTemplate(LoanPageTemplateInfoView view) {
        LoanPageTemplateInfo pageTemplateInfo;
        if (view.getId() != null){
            pageTemplateInfo = templateInfoRepository.findOne(view.getId());
        }else {
            pageTemplateInfo = new LoanPageTemplateInfo();
        }
        BeanUtils.copyProperties(view, pageTemplateInfo);

        if (pageTemplateInfo.getId() != null){
            moduleRepository.deleteAllByTemplateId(pageTemplateInfo.getId());
            productRepository.deleteAllByTemplateId(pageTemplateInfo.getId());
        }
        if (pageTemplateInfo.getStatus() == null) {
            pageTemplateInfo.setStatus(0); //默认下线状态
        }
        LoginUser loginUser = CurrentUser.get();
        pageTemplateInfo.setUpdator(loginUser.getName());
        saveOrUpdate(pageTemplateInfo);

        List<LoanPageTemplateInfoView.ModuleItem> allModuleItems = new ArrayList<>();
        allModuleItems.addAll(view.getShowUserModuleItems());
        allModuleItems.addAll(view.getGloablModuleItems());
        moduleRepository.save(allModuleItems.stream().map(m -> {
            LoanPageTemplateModule templateModule = new LoanPageTemplateModule();
            BeanUtils.copyProperties(m, templateModule);
            templateModule.setTemplateId(pageTemplateInfo.getId());
            return templateModule;
        }).collect(Collectors.toList()));

        if (!view.getSubstitute()){
            productRepository.save(view.getSelectedOnlineProducts().stream().map(p -> {
                LoanPageTemplateProduct templateProduct = new LoanPageTemplateProduct();
                templateProduct.setProductId(Integer.parseInt(p));
                templateProduct.setTemplateId(pageTemplateInfo.getId());
                return templateProduct;
            }).collect(Collectors.toList()));
        }
        view.setId(pageTemplateInfo.getId());
        return pageTemplateInfo;
    }

    @Override
    public LoanPageTemplateInfoView loadPageTemplateInfoView(Long pageTemplateId) {
        LoanPageTemplateInfoView view = new LoanPageTemplateInfoView();
        LoanPageTemplateInfo pageTemplateInfo = templateInfoRepository.findOne(pageTemplateId);
        if (pageTemplateInfo != null){
            BeanUtils.copyProperties(pageTemplateInfo, view);
        }

        List<LoanPageTemplateModule> templateModules = moduleRepository.findAllByTemplateId(pageTemplateId);
        if (CollectionUtils.isNotEmpty(templateModules)){
            List<LoanPageTemplateInfoView.ModuleItem> globalModules = templateModules.stream().filter(x -> x.getUserType() == -1)
                    .map(x -> {
                        LoanPageTemplateInfoView.ModuleItem item = new LoanPageTemplateInfoView.ModuleItem();
                        BeanUtils.copyProperties(x, item);
                        return item;
                    }).collect(Collectors.toList());
            view.setGloablModuleItems(globalModules);

            List<LoanPageTemplateInfoView.ModuleItem> userModules = templateModules.stream().filter(x -> x.getUserType() == pageTemplateInfo.getUserType())
                    .map(x -> {
                        LoanPageTemplateInfoView.ModuleItem item = new LoanPageTemplateInfoView.ModuleItem();
                        BeanUtils.copyProperties(x, item);
                        return item;
                    }).collect(Collectors.toList());
            view.setShowUserModuleItems(userModules);
        }

        List<LoanPageTemplateProduct> templateProducts = productRepository.findAllByTemplateId(pageTemplateId);
        if (CollectionUtils.isNotEmpty(templateModules)){
            view.setSelectedOnlineProducts(templateProducts.stream().map(x -> x.getProductId().toString()).collect(Collectors.toSet()));
        }

        return view;
    }

    @Override
    public List<LoanPageTemplateInfoServiceImpl.CommProductVo> getProducts(List<CommProductId> allProducts, Long pageTemplateId) {
        List<LoanPageTemplateProduct> templateProducts = productRepository.findAll();
        if (pageTemplateId != null){
            templateProducts = templateProducts.stream().filter(p -> {
                return p.getTemplateId() != pageTemplateId;
            }).collect(Collectors.toList());
        }
        List<Integer> selectedPid = templateProducts.stream().map(p -> p.getProductId()).collect(Collectors.toList());
        List<CommProductVo> collect = allProducts.stream().filter(x -> x.getRealPrdid() != null && x.getIsApp() == 1)
                .map(p -> {
                    CommProductVo cvo = new CommProductVo();
                    BeanUtils.copyProperties(p, cvo);
                    cvo.setHadSet(selectedPid.contains(p.getProductId()));
                    return cvo;
                }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public void online(LoanPageTemplateInfo templateInfo) {
        online(Lists.newArrayList(templateInfo));
    }

    @Override
    public void online(List<LoanPageTemplateInfo> templateInfos) {
        templateInfos.stream().forEach(t -> {
            t.setStatus(1);
            saveOrUpdate(t);
        });
    }

    @Override
    public void offline(LoanPageTemplateInfo templateInfo) {
        offline(Lists.newArrayList(templateInfo));
    }

    @Override
    public void offline(List<LoanPageTemplateInfo> templateInfos) {
        templateInfos.stream().forEach(t -> {
            t.setStatus(0);
            saveOrUpdate(t);
        });
    }

    @Override
    public void deleteTemplate(LoanPageTemplateInfo templateInfo) {
        delete(templateInfo);
        moduleRepository.deleteAllByTemplateId(templateInfo.getId());
        productRepository.deleteAllByTemplateId(templateInfo.getId());
    }

    @Override
    public List<LoanPageTemplateInfo> findSubstitute() {
        List<LoanPageTemplateInfo> allBySubstitute = templateInfoRepository.findAllBySubstitute(true);
        return allBySubstitute;
    }

    @Data
    public static class CommProductVo{
        private String name;
        private Integer productId;
        private boolean hadSet;
    }
}
